#ifndef VMAIN_H
#define VMAIN_H

#include "VBase.h"
#include "VPlayer.h"

class VSqlProcessor;

class VUi;
class VBottomButtons;
class VIndex;
class VVodList;

class VMain :
    public VBase
{
    friend int main(int, char**);
public:
    VMain(void);
    ~VMain(void);

protected:
    VUi* _ui;

    VUi* _mainui;       // lv-1
    VUi* _singerui;     // lv-2
    VUi* _catagoryui;
    VUi* _languageui;
    VUi* _rankui;
    VUi* _popui;
    VUi* _lyricsui;
    VUi* _pinyinui;
    VUi* _songsui;      // lv-3

    VBottomButtons* _bottombuttons; // widget-ui

protected:
    static SDL_Surface* _sfc;
    static VMain* _pmain;
    static unsigned int _autoincrements[INC_MAX];
    static unsigned long _rtid;
#ifdef UNDER_CE
    static VPlayer* s_player;
#endif  // UNDER_CE
    static VVodList* s_vodlist;
#ifdef UNDER_CE
    static EGLSurface s_eglSurface;
    static EGLDisplay s_eglXDisplay;
#endif
    static unsigned long s_timerInterval[TIMER_MAX];
    static unsigned long s_timerValue[TIMER_MAX];

    static VSqlProcessor* s_db;


public: // static interface
    static VMain* getMain(void);

    static VVodList* getVodList(void);

    static unsigned int getIncreament(WHICH_INCREAMENT);
    static void resetIncreament(WHICH_INCREAMENT);
    static void resetAllIncreament(void);

    static void getCursorPos(unsigned short* x, unsigned short* y);

    static SDL_Surface* getSurface(void);
    static VUi* queryUi(which_ui_t whichui);

    static VUi* switchToUi(VUi* whichui);
    static VUi* switchToUi(which_ui_t whichui);

    static void resetViewport();

    static int rand();

    static void resetGLEnviroment();

    static const std::string getSkin(const char* format, ...);
    static const std::string getPicture(const char* format, ...);

    static bool loadTexture(
        const std::string& filename, GLuint* texture,
        GLint* width = NULL, GLint* height = NULL,
        GLint* bpp = NULL);
    static GLuint makeSurfaceTexture(SDL_Surface* sfc);
    static bool deleteTexture(GLuint* texture);

    static bool exit(int, int, VButton*);

    static void ansi2Unicode(const char* lpString, wchar_t* lpUni);
    static std::string utf82gbk(const std::string& utf8);
    static std::string gbk2utf8(const std::string& gbk);

    static int getClock();
    static int delay(unsigned int ms);

    static void returnMainUi(int, int, VButton*);

    static void drawTexture(GLuint texture, int x, int y, int w, int h);
    static void drawReflection(GLuint texture, int x, int y, int w, int h, GLfloat br = 0);

    static VSqlProcessor* getDatabase();

    template<class RETTYPE, class INPUTTYPE>
    inline static RETTYPE castto(const INPUTTYPE& input);
    template<class RETTYPE, class INPUTTYPE>
    inline static RETTYPE castto(INPUTTYPE input);

    static bool stringStartWith(const std::string& longstring, const std::string& headstring);

    static bool inRect(
        int left, int top, int right, int bottom,
        int posx, int posy);

    static void* bsearch(
        const void* key,
        const void* base,
        size_t num,
        size_t width,
        int (*compare)(const void*, const void*)
    );




#ifdef UNDER_CE
    static VPlayer* getPlayer();
#endif

    const unsigned long getRuntimeID();


public:

public: // interface
    void init(void);
    void exec(void);

public: // event handler
    void render();

protected:  // private member functions
    void initVMainMembers();
    void initEnvironment();
    void initComponents();
    void initSDL();
    void setupSDLSurface();
    void initOpenGL();
    void initLogSystem();
    void initDebugLogSystem();
    bool initEGL();
    void initPlayer();
    void initDatabaseModule();
    bool setupDatabaseTables();
    void loadData();



public:
    //
    static bool handler(int, int, VButton*);
    //

#ifdef DEBUG
    void debugTest();
#endif
};

#endif // VMAIN_H
